#pragma once 
#include <vector>
#include <ECS/ECS.h>
#include <ECS/Math/Vec2.h>
#include <ECS/Patterns/Nullable.h>

class Transform;

struct TransformDef
{
	mtMETA_DEC;
	ECS::Nullable<float> x;
	ECS::Nullable<float> y;
	ECS::Nullable<float> angle;
};

class TransformClient
{
public:
	typedef std::function<void(const ECS::Vec2<float>&, float)> updateFunction_t;
	TransformClient(Transform* t);
	void setTransform(const ECS::Vec2<float>& position, float angle);
	updateFunction_t updateFunction;
protected:
	Transform* _transform;
};

class Transform : public ECS::Component
{
	friend class TransformClient;
	mtMETA_DEC;
public:
	Transform();
	bool initWith(TransformDef* def);

	const ECS::Vec2<float>& getPosition() const;
	void setPosition(float x, float y);
	void setPosition(const ECS::Vec2<float>& position);

	float getAngle() const;
	void setAngle(float angle);

	TransformClient* createClient(TransformClient::updateFunction_t foo);

	Signal<void (const ECS::Vec2<float>&, const ECS::Vec2<float>&)> eventMoved;
protected:
	ECS::Vec2<float> _position;
	float _angle;
	std::vector<TransformClient*> _clients;

	void setTransform(TransformClient* sender, const ECS::Vec2<float>& position, float angle);

	void NotifyClientsExceptOf( TransformClient* sender = nullptr);

};
